package com.renfei.multimediatask.ui.task4;


import android.annotation.TargetApi;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.os.AsyncTask;
import android.os.Build;
import android.view.View;
import android.widget.TextView;

import com.renfei.multimediatask.R;
import com.renfei.multimediatask.base.BaseActivity;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * 此demo是 将两个视频分别取 音频数据和视频数据 重新合成为一个新的视频
 */
public class MediaMuxerDemoActivity extends BaseActivity {

    private static final String TAG = MediaMuxerDemoActivity.class.getSimpleName();

    @BindView(R.id.tv_mediamuxer_video)
    TextView tvMediamuxerVideo;


    private String resourceAduioFile ;//= BASE_PATH + "renshenga.mp4";
    private String resourceVideoFile ;//= BASE_PATH + "bank_xiaojiejie.mp4";


    private static final String VIDEO_TYPE = "video/";

    private static final String AUDIO_TYPE = "audio/";
    /**
     * 合成的视频文件地址
     */
    private String newVideoFile ;//= BASE_PATH + "createdVideo.mp4";

    @Override
    protected int getLayoutId() {
        return R.layout.act_mediamuxer_demo;
    }

    @Override
    protected void initListener() {
        resourceAduioFile   =getParentFilePath()   +   "renshenga.mp4";
        resourceVideoFile   =getParentFilePath()   +   "bank_xiaojiejie.mp4";
        newVideoFile        =getParentFilePath()   +   "createdVideo.mp4";
    }

    @OnClick(R.id.tv_mediamuxer_video)
    public void onViewClicked() {

        File audioFile = new File(resourceAduioFile);
        File videoFile = new File(resourceVideoFile);

        if (!audioFile.exists()) {
            showToast("音频源文件不存在");
            return;
        }
        if (!videoFile.exists()) {
            showToast("视频源文件不存在");
            return;
        }

        File targetFile = new File(newVideoFile);

        if (targetFile.exists()) {
            try {
                targetFile.delete();
                targetFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        MuxerVideoTask task = new MuxerVideoTask(new WeakReference<>(MediaMuxerDemoActivity.this));
        task.execute();


    }


    static class MuxerVideoTask extends AsyncTask<Void, Integer, Integer> {
        private WeakReference<MediaMuxerDemoActivity> weakReference;

        public MuxerVideoTask(WeakReference<MediaMuxerDemoActivity> weakReference) {
            this.weakReference = weakReference;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            weakReference.get().showLoadingDialog();
        }

        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        protected Integer doInBackground(Void... voids) {
            weakReference.get().loge(TAG, "MuxerVideoTask   doInBackground ");

            try {
                int maxAudioSize = 0;//音频最大缓冲区大小
                int maxFrameSize = 0; //视频帧最大缓冲区大小
                int frameRate = 0;//视频帧率

                int targetAudioTrackIndex = -1;
                int targetVideoTracKIndex = -1;

                MediaMuxer mediaMuxer = new MediaMuxer(weakReference.get().newVideoFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);


                MediaExtractor audioResourceExtractor = new MediaExtractor();
                audioResourceExtractor.setDataSource(weakReference.get().resourceAduioFile);
                int audioResourceTrackCount = audioResourceExtractor.getTrackCount();

                /**
                 * 在这里碰到个问题，
                 * audioResourceExtractor.getTrackFormat(i) 不一定存在
                 * 所以遍历时会报错(目前没有好的处理方法)
                 */

                for (int i = 0; i < audioResourceTrackCount; i++) {
                    MediaFormat format = audioResourceExtractor.getTrackFormat(i);
                    String currentMineType = format.getString(MediaFormat.KEY_MIME);
                    if (currentMineType.startsWith(AUDIO_TYPE)) {
                        audioResourceExtractor.selectTrack(i);
                        targetAudioTrackIndex = mediaMuxer.addTrack(format);
                        //获取音频最大输入，为了计算缓冲区大小
                        maxAudioSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
                        break;
                    }
                }

                MediaExtractor videoResourceExtractor = new MediaExtractor();
                audioResourceExtractor.setDataSource(weakReference.get().resourceVideoFile);
                int videoResourceTrackCount = audioResourceExtractor.getTrackCount();
                for (int i = 0; i < videoResourceTrackCount; i++) {
                    MediaFormat format = audioResourceExtractor.getTrackFormat(i);
                    String currentMineType = format.getString(MediaFormat.KEY_MIME);
                    if (currentMineType.startsWith(VIDEO_TYPE)) {
                        videoResourceExtractor.selectTrack(i);
                        targetVideoTracKIndex = mediaMuxer.addTrack(format);

                        //获取视频帧最大值，为了后面合成新视频，读取文件时候设定缓冲区大小
                        maxFrameSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
                        //获取视频帧率,为了后面计算获取到的文件处于的播放时间
                        frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
                        break;
                    }

                }
                weakReference.get().loge(TAG, "MuxerVideoTask doInBackground   mediaMuxer.start()  ");
                mediaMuxer.start();

                /**
                 * 首先添加音频数据
                 */
                if (-1 != targetAudioTrackIndex) {
                    MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo();
                    ByteBuffer audioByteBuffer = ByteBuffer.allocate(maxAudioSize);
                    int audioSampleSize = 0;
                    while ((audioSampleSize = audioResourceExtractor.readSampleData(audioByteBuffer, 0)) > 0) {
                        audioBufferInfo.offset = 0;
                        audioBufferInfo.size = audioSampleSize;
                        audioBufferInfo.flags = audioResourceExtractor.getSampleFlags();
                        audioBufferInfo.presentationTimeUs += 1000 * 1000 / frameRate;
                        mediaMuxer.writeSampleData(targetAudioTrackIndex, audioByteBuffer, audioBufferInfo);

                        audioResourceExtractor.advance();
                    }
                }

                /**
                 * 添加视频数据
                 */
                if (-1 != targetVideoTracKIndex) {
                    MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo();
                    ByteBuffer videoByteBuffer = ByteBuffer.allocate(maxFrameSize);
                    int videoSampleSize = 0;

                    while ((videoSampleSize = videoResourceExtractor.readSampleData(videoByteBuffer, 0)) > 0) {

                        videoBufferInfo.offset = 0;
                        videoBufferInfo.size = videoSampleSize;
                        videoBufferInfo.flags = videoResourceExtractor.getSampleFlags();
                        videoBufferInfo.presentationTimeUs += 1000 / 1000 / frameRate;
                        mediaMuxer.writeSampleData(targetVideoTracKIndex, videoByteBuffer, videoBufferInfo);

                        videoResourceExtractor.advance();
                    }

                }


            } catch (IOException e) {
                e.printStackTrace();
            }

            return 0;
        }

        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);
            weakReference.get().dismissDialog();

            weakReference.get().showToast("合成视频已完成");
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
            weakReference.get().dismissDialog();
        }
    }


}
